// src/common/interceptors/global-date-format.interceptor.ts
import {
    CallHandler,
    ExecutionContext,
    Injectable,
    NestInterceptor,
  } from '@nestjs/common';
  import { Observable } from 'rxjs';
  import { map } from 'rxjs/operators';
  
  // 自定义日期格式
  const DATE_FORMAT = 'YYYY/MM/DD HH:mm:ss';
  const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?$/;
  const DATE_STRING_REGEX = /^(?:19|20)\d\d[-/](?:0[1-9]|1[012])[-/](?:0[1-9]|[12][0-9]|3[01])T?(?:\d{2}:\d{2}:\d{2})?$/;
  
  @Injectable()
  export class GlobalDateFormatInterceptor implements NestInterceptor {
    intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
      return next.handle().pipe(
        map((data) => {
          return this.deepFormatDates(data);
        })
      );
    }
  
    /**
     * 深度递归格式化所有日期字段
     * @param data 输入数据
     * @returns 格式化后的数据
     */
    private deepFormatDates(data: any): any {
      if (data === null || data === undefined) {
        return data;
      }
      
      // 处理数组
      if (Array.isArray(data)) {
        return data.map(item => this.deepFormatDates(item));
      }
      
      // 处理日期对象
      if (data instanceof Date) {
        return this.formatDate(data);
      }
      
      // 处理日期字符串
      if (typeof data === 'string') {
        if (this.isDateString(data)) {
          return this.formatDate(new Date(data));
        }
        return data;
      }
      
      // 处理普通对象
      if (typeof data === 'object') {
        return Object.entries(data).reduce((acc, [key, value]) => {
          // 递归处理嵌套属性
          acc[key] = this.deepFormatDates(value);
          
          // 保留原始值和格式化值的映射（可选）
          if (key.toLowerCase().includes('timestamp')) {
            acc[`${key}Formatted`] = acc[key];
          }
          
          return acc;
        }, {} as Record<string, any>);
      }
      
      // 其他类型直接返回
      return data;
    }
  
    /**
     * 检查字符串是否是日期格式
     * @param value 要检查的字符串
     * @returns 是否是日期字符串
     */
    private isDateString(value: string): boolean {
      // 常见的日期格式识别
      if (ISO_DATE_REGEX.test(value)) return true;
      if (DATE_STRING_REGEX.test(value)) return true;
      
      try {
        const date = new Date(value);
        return !isNaN(date.getTime());
      } catch (e) {
        return false;
      }
    }
  
    /**
     * 格式化日期为指定格式
     * @param date 日期对象
     * @returns 格式化后的日期字符串
     */
    private formatDate(date: Date): string {
      if (isNaN(date.getTime())) return 'Invalid Date';
      
      const year = date.getFullYear();
      const month = (date.getMonth() + 1).toString().padStart(2, '0');
      const day = date.getDate().toString().padStart(2, '0');
      const hours = date.getHours().toString().padStart(2, '0');
      const minutes = date.getMinutes().toString().padStart(2, '0');
      const seconds = date.getSeconds().toString().padStart(2, '0');
      
      return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
    }
  }